package com.weilele.mvvm.base

import com.weilele.mvvm.utils.coroutine.createCoroutine
import kotlinx.coroutines.*
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext

/**
 * 描述：mvvm - 基类Model
 * 只处理数据获取
 */
open class MvvmModel {
    /**
     * 创建一个主线程的协程作用域
     */
    private val mCoroutine by lazy { createCoroutine(Dispatchers.Main) }

    /**
     * 利用自己创建（作用域）启动一个协程
     *  mCoroutine 默认运行再 代码块运行在主线程
     */
    fun launchWithScope(
            context: CoroutineContext = EmptyCoroutineContext,
            start: CoroutineStart = CoroutineStart.DEFAULT,
            block: suspend CoroutineScope.() -> Unit
    ): Job {
        return mCoroutine.launch(context, start, block)
    }

    /**
     * 利用viewModelScope（作用域）启动一个协程
     *  CoroutineStart.DEFAULT 代码块运行在主线程
     */
    fun <T> asyncWithScope(
            context: CoroutineContext = EmptyCoroutineContext,
            start: CoroutineStart = CoroutineStart.DEFAULT,
            block: suspend CoroutineScope.() -> T
    ): Deferred<T> {
        return mCoroutine.async(context, start, block)
    }

    /**
     * 同步viewModel的onCleared
     */
    open fun onCleared() {
        callList.forEach {
            if (!it.isCanceled()) {
                it.cancel()
            }
        }
        callList.clear()
        callListRetrofit.forEach {
            if (!it.isCanceled) {
                it.cancel()
            }
        }
        callListRetrofit.clear()
        mCoroutine.cancel()
    }

    private val callList = mutableListOf<okhttp3.Call>()

    /**
     * 销毁的时候结束请求
     */
    fun okhttp3.Call.cancelOnDestroy(): okhttp3.Call {
        callList.add(this)
        return this
    }

    /**
     * retrofit
     */
    private val callListRetrofit = mutableListOf<retrofit2.Call<*>>()


    fun <BO> retrofit2.Call<BO>.cancelOnDestroy(): retrofit2.Call<BO> {
        callListRetrofit.add(this)
        return this
    }
}